package officeserver.office.request;

import java.util.ArrayList;
import java.util.logging.Level;

import officeserver.log_error.UserException;
import officeserver.log_error.UserException.REASON;
import officeserver.office.Office;
import officeserver.users.AccessLevel;
import officeserver.users.PersonalInfo;
import officeserver.users.User;

public class UserRequest extends OfficeRequest {
    public enum TYPE {
	USER_LOGIN, USER_LOGOUT, IS_LOGGED_IN, USER_SEARCH, USER_ADD, USER_REMOVE, USER_INFO, SET_USER_INFO, GET_ALL_USERS
    }

    protected TYPE type;
    protected boolean self;

    public UserRequest(TYPE type, Object... myArgs) {
	this.type = type;
	this.setArgs(myArgs);
    }
    public String toString()
    {
    	return "UserRequest " + this.getType();
    }
    /*
     * (non-Javadoc)
     * 
     * @see
     * officeserver.office.network.OfficeRequest#processRequest(officeserver
     * .office.Office)
     */
    @Override
    public void processRequest(Office in) {
	switch (type) {
	case USER_ADD:
	    processAdd(in);
	    break;
	case USER_LOGIN:
	    processLogin(in);
	    break;
	case USER_LOGOUT:
	    processLogout(in);
	    break;
	case IS_LOGGED_IN:
	    checkLogin(in);
	    break;
	case USER_SEARCH:
	    processSearch(in);
	    break;
	case SET_USER_INFO:
	    directionIn = true;
	case USER_INFO:
	    processInfo(in);
	    break;
	case USER_REMOVE:
	    processRemove(in);
	    break;
	case GET_ALL_USERS:
	    processAllUsers(in);
	
	    break;
	}
    }

    private void processAllUsers(Office in) {
	try {
	    data = new Object[1];

	    data[0] = in.getAllUsers();
	} catch (Exception e) {
	    error = e;
	}
    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void processRemove(Office in) {
	try {
	    in.deleteSearchUser();
	} catch (Exception e) {
	    error = e;
	}

    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void processInfo(Office in) {
	try {
	    if (directionIn) {
		if (this.self) {
		    in.setSelfPersonalInfo((PersonalInfo) args[0]);
		} else {
		    in.setSearchPersonalInfo((PersonalInfo) args[0]);
		}
	    } else {
		if (this.self) {
		    this.data = new PersonalInfo[1];
		    this.data[0] = in.getSelfPersonalInfo();
		} else {
		    this.data = new PersonalInfo[1];
		    this.data[0] = in.getSearchPersonalInfo();
		}
	    }
	} catch (Exception e) {
	    error = e;
	}
    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void processAdd(Office in) {
	if (args.length >= 5) {
	    try {
		in.addUser(((String) args[0]), ((String) args[1]),
			((String) args[2]), ((String) args[3]),
			((officeserver.users.AccessLevel) args[4]));
	    } catch (Exception e) {
		error = e;
	    }
	} else {
	    error = new RequestException(
		    RequestException.REASON.INVALID_NUMBER_OF_ARGUMENTS);
	}
    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void processLogin(Office in) {
	if (args.length >= 2) {
	    try {
		in.userLogin(((String) args[0]), ((String) args[1]));
		error = null;
	    } catch (Exception e) {
		error = e;
	    }
	} else {
	    error = new RequestException(
		    RequestException.REASON.INVALID_NUMBER_OF_ARGUMENTS);
	}
    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void processLogout(Office in) {
	try {
	    in.userLogout();
	} catch (Exception e) {
	    error = e;
	}
    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void checkLogin(Office in) {
	try {
	    data = new Object[1];
	    data[0] = in.isLoggedIn() ? "true" : "false";
	    if( ((String)data[0]).equals("true") ) 
	    	System.out.println("we are logged in");
	} catch (Exception e) {
	    error = e;
	}
    }

    /**
     * @author Chris Bayruns
     * @return the self
     */
    public boolean isSelf() {
	return self;
    }

    /**
     * @author Chris Bayruns
     * @param self
     *            the self to set
     */
    public void setSelf(boolean self) {
	this.self = self;
    }

    /**
     * @author Chris Bayruns
     * @param in
     *            The office object to act on.
     */
    private void processSearch(Office in) {
	try {
	    in.clearSearch();
	    if (args.length == 2) {
		if (args[1] instanceof AccessLevel) {
		    in.userSearch(((Integer) args[0]), ((AccessLevel) args[1]));
		} else {
		    in.userSearch(((String) args[0]), ((String) args[1]));
		}
	    } else if (args.length == 1) {
		in.userSearch(((String) args[0]));
	    } else {
		throw (new RequestException(
			RequestException.REASON.INVALID_NUMBER_OF_ARGUMENTS));
	    }
	} catch (Exception e) {
	    error = e;
	}
    }

    /**
     * @author Chris Bayruns
     * @return theType
     */
    public TYPE getType() {
	return type;
    }

    /**
     * @author Chris Bayruns
     * @param type
     *            Set the type to type
     */
    public void setType(TYPE type) {
	this.type = type;
    }
}
